package userinterceptor

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/go-playground/validator"
	"strconv"
	"strings"
	"time"
	"vpn-management-server/logger"
	"vpn-management-server/network"
	"vpn-management-server/security/code"
	"vpn-management-server/src/model/adminlogmodel"
	"vpn-management-server/src/model/adminmodel"
	"vpn-management-server/src/model/usermodel"
	"vpn-management-server/src/service/adminlogservice"
	"vpn-management-server/src/service/adminservice"
	"vpn-management-server/src/service/userservice"
	"vpn-management-server/src/service/whitelistservice"
)

func UserSimAuthValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	var user usermodel.User
	err := json.Unmarshal(request.Parameters, &user)
	logger.Logger.Debug(user)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to user error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(user)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}

	if user.Phone == "" {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "phone is empty,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "phone is empty,"
		return false
	}
	// TODO 加入对身份的验证
	request.SetModel(&user)
	return true
}

func UserSimAuthStatusValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	type Task struct {
		TaskID string `json:"transactionId"`
	}
	var task Task
	err := json.Unmarshal(request.Parameters, &task)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to string error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}

	valid := validator.New()
	err = valid.Struct(task)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	if strings.TrimSpace(task.TaskID) == "" {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "taskId is empty or only whitespace", nil)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "String cannot be empty"
		return false
	}
	request.SetModel(task.TaskID)
	return true
}

func UserTokenRegisterValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	var user usermodel.User
	err := json.Unmarshal(request.Parameters, &user)
	logger.Logger.Debug(user)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to user error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(user)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	// TODO 对白名单和激活码进行验证
	//result := whitelistservice.ValidateWhiteItemService(ctx, user.Phone, user.Invitation)
	//if !result {
	//	logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate phone or invitation fail")
	//	response.Code = code.BAD_REQUEST
	//	response.ErrorMsg = "validate phone or invitation fail"
	//	return false
	//}
	// TODO 对邮箱的唯一性验证 返回的结果是是否验证成功
	//result = userservice.ValidateEmailService(ctx, user.Email)
	//if !result {
	//	logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Duplicate email")
	//	response.Code = code.BAD_REQUEST
	//	response.ErrorMsg = "Duplicate email"
	//	return false
	//}
	// TODO 加入对身份的验证
	request.SetModel(&user)
	return true
}

func UserValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	// TODO 解析json到user结构体
	var user usermodel.User
	err := json.Unmarshal(request.Parameters, &user)
	logger.Logger.Debug(user)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to user error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(user)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	// TODO 对白名单和激活码进行验证
	result := whitelistservice.ValidateWhiteItemService(ctx, user.Phone, user.Invitation)
	if !result {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate phone or invitation fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate phone or invitation fail"
		return false
	}
	// TODO 对邮箱的唯一性验证 返回的结果是是否验证成功
	result = userservice.ValidateEmailService(ctx, user.Email)
	if !result {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Duplicate email")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "Duplicate email"
		return false
	}
	// TODO 加入对身份的验证
	request.SetModel(&user)
	return true
}

func UserLoginValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	// TODO 解析json到UserLogin结构体
	var userLogin usermodel.UserLogin
	err := json.Unmarshal(request.Parameters, &userLogin)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to userLogin error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(userLogin)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	// TODO 验证身份的合法性

	// TODO 验证设备信息
	request.SetModel(&userLogin)
	return true
}

func UserResetValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	// TODO 解析json到UserReset结构体
	var userReset usermodel.UserReset
	err := json.Unmarshal(request.Parameters, &userReset)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to userReset error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(userReset)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	// TODO 验证身份的合法性

	// TODO 验证设备信息
	request.SetModel(&userReset)
	return true
}

func UserResetByAdminValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	// TODO 解析json到UserReset结构体
	var UserResetByAdmin usermodel.UserResetByAdmin
	err := json.Unmarshal(request.Parameters, &UserResetByAdmin)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to userReset error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(UserResetByAdmin)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	// TODO 验证管理员权限等级
	if rank := adminservice.GetAdminRankService(ctx, request, response); rank == adminmodel.SuperAdmin || rank == adminmodel.SystemAdmin || rank == adminmodel.UserGroupAdmin {
		request.SetModel(&UserResetByAdmin)
		return true
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "have no authority")
		response.Code = code.UNAUTHORIZED
		response.ErrorMsg = "have no authority"
		return false
	}
}

// UserNameInfoValidator 删除操作前置拦截器 超级管理员 系统管理员 用户组管理员可以操作
func UserNameInfoValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	var userNameInfo usermodel.UserNameInfo
	err := json.Unmarshal(request.Parameters, &userNameInfo)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to userReset error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}
	// TODO 验证json字段的合法性
	valid := validator.New()
	err = valid.Struct(&userNameInfo)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}
	// TODO 验证管理员权限
	if rank := adminservice.GetAdminRankService(ctx, request, response); rank == adminmodel.UserGroupAdmin || rank == adminmodel.SystemAdmin || rank == adminmodel.SuperAdmin {
		request.SetModel(&userNameInfo)
		return true
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "have no authority")
		response.Code = code.UNAUTHORIZED
		response.ErrorMsg = "have no authority"
		return false
	}
}

func UserNameValidator(ctx context.Context, request *network.NetRequest, response *network.NetResponse) bool {
	var userName usermodel.UserName
	err := json.Unmarshal(request.Parameters, &userName)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "UnMarshal Parameters to UserName error,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "parse parameters fail"
		return false
	}

	valid := validator.New()
	err = valid.Struct(&userName)
	if err != nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "validate Parameters fail,", err)
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "validate parameters fail"
		return false
	}

	request.SetModel(&userName)
	return true
}

// AddUserLogToChan TODO 生成注册日志发送给区块链
func AddUserLogToChan(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {

}

// DeleteUserLogToChan 删除用户生成日志加入到chan
func DeleteUserLogToChan(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	userNameInfo := request.GetModel().(*usermodel.UserNameInfo)
	adminlogservice.AddAdminLogToChan(adminlogservice.ChanAdminLogs, adminlogmodel.AdminLog{
		Name:      adminservice.GetCurrAdminService(ctx, request, response).Name,
		Source:    request.GetRemote(),
		Location:  "地址",
		Behavior:  "删除用户" + userNameInfo.Name,
		TimeStamp: strconv.FormatInt(time.Now().Unix(), 10),
	})
}

func RevokeUserLogToChan(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	userNameInfo := request.GetModel().(*usermodel.UserNameInfo)
	adminlogservice.AddAdminLogToChan(adminlogservice.ChanAdminLogs, adminlogmodel.AdminLog{
		Name:      adminservice.GetCurrAdminService(ctx, request, response).Name,
		Source:    request.GetRemote(),
		Location:  "地址",
		Behavior:  "封禁用户" + userNameInfo.Name,
		TimeStamp: strconv.FormatInt(time.Now().Unix(), 10),
	})
}

func RecoverUserLogToChan(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	userNameInfo := request.GetModel().(*usermodel.UserNameInfo)
	adminlogservice.AddAdminLogToChan(adminlogservice.ChanAdminLogs, adminlogmodel.AdminLog{
		Name:      adminservice.GetCurrAdminService(ctx, request, response).Name,
		Source:    request.GetRemote(),
		Location:  "地址",
		Behavior:  "解封用户" + userNameInfo.Name,
		TimeStamp: strconv.FormatInt(time.Now().Unix(), 10),
	})
}

func ResetUserLogToChan(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if UserReset, ok := request.GetModel().(*usermodel.UserResetByAdmin); ok {
		adminlogservice.AddAdminLogToChan(adminlogservice.ChanAdminLogs, adminlogmodel.AdminLog{
			Name:      adminservice.GetCurrAdminService(ctx, request, response).Name,
			Source:    request.GetRemote(),
			Location:  "地址",
			Behavior:  fmt.Sprintf("修改用户%s的密码", UserReset.Name),
			TimeStamp: strconv.FormatInt(time.Now().Unix(), 10),
		})
	}
}
